﻿using System.Net;
using AnjLab.SyncIT.Core.Api;
using System;
using AnjLab.SyncIT.Core.Data.Outlook;

namespace AnjLab.SyncIT.Core.Data.DotProject
{
    public class DotProjectTaskDao : ISourceTaskDao
    {
        private readonly Source _source;
        private readonly DotProjectUIParser _parser;

        public DotProjectTaskDao(Source source)
        {
            _source = source;
            _parser = new DotProjectUIParser(_source);
        }

        public void Dispose()
        {
        }

        public DotProjectUIParser Parser
        {
            get { return _parser; }
        }

        public string[] GetChangedTasks()
        {
            return _parser.ParseMyTODOList();
        }

        public ISourceTask Get(string taskID)
        {
            try
            {
                return _parser.ParseTask(taskID);
            }
            catch (WebException e)
            {
                if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.NotFound)
                {
                    return null;
                }
                throw;
            }
        }

        public bool CanTrackTaskLifetime
        {
            get { return false; }
        }

        public void CheckConnection()
        {
            _parser.Ping();
        }

        public bool SupportsBackSynchronization
        {
            get { return !_source.CustomizeSubject; }
        }

        public void MergeTasks(ISourceTask task, IOutlookItem outlookTask)
        {
            if (!(task is Task))
            {
                throw new ArgumentException("Task should be of type Dot Project task", "task");
            }

            var dotProjectTask = ((Task) task);

            bool changed = false;

            if (outlookTask.PercentComplete != dotProjectTask.Progress)
            {
                //  Update progress in the source
                dotProjectTask.Progress = outlookTask.PercentComplete
                                        - outlookTask.PercentComplete % 5;
                changed = true;
            }

            if (outlookTask.Complete && !task.IsClosed)
            {
                //  Close the task in the source: set status to Inactive
                dotProjectTask.StatusCode = StatusCode.Inactive;
                dotProjectTask.Status = DotProjectUIParser.ConvertStatusCodeToStatusId(dotProjectTask.StatusCode);
                dotProjectTask.Progress = 100;
                changed = true;
            }

            var subject = OutlookTicketDao.ExtractSummaryFromSubject(outlookTask.Subject);

            if (!string.Equals(subject, task.Summary, StringComparison.InvariantCulture))
            {
                //  Update Summary in the source
                dotProjectTask.Summary = subject;
                changed = true;
            }

            if (outlookTask.Importance != OutlookTicketDao.ConvertToOutlookImportance(task.Importance))
            {
                //  Update priority in the source
                dotProjectTask.Importance = OutlookTicketDao.ConvertFromOutlookImportance(outlookTask.Importance);
                dotProjectTask.Priority = DotProjectUIParser.ConvertImportanceToPriorityId(dotProjectTask.Importance);
                changed = true;
            }

            if (changed)
            {
                //  Post task data back to dotProject
                Library.Log.Debug("Some task data need to be sync with the source backend. Processing...");

                _parser.SendTaskDataBack(dotProjectTask);
                
                Library.Log.Debug("Done");
            }
            else
            {
                Library.Log.Debug("Nothing to sync with taskID = {0}", task.ID);
            }
        }
    }
}
